/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package ru.ssau.lib;

import java.awt.GridBagLayout;
import java.awt.event.*;
import java.util.*;
import javax.swing.*;

/**
 *
 * @author Дима
 */
public class DateSetPanel extends JPanel {

    private int year;
    private int month;
    private int day;
    private int hours;
    private int minutes;
    private int seconds;

    private JTextField dayField;
    private JTextField monthField;
    private JTextField yearField;
    private JTextField hoursField;
    private JTextField minutesField;
    private JTextField secondsField;

    private JRadioButton setDateButton;
    private JRadioButton currentDateButton;

    private ButtonGroup buttonGroup;

    public DateSetPanel() {
        initComponents();
        layoutComponents();
    }

    private void initComponents() {
        dayField = new JTextField(3);
        monthField = new JTextField(3);
        yearField = new JTextField(5);
        hoursField = new JTextField(3);
        minutesField = new JTextField(3);
        secondsField = new JTextField(3);

        setDateButton = new JRadioButton("Set date", true);
        setDateButton.addActionListener(new DateFieldsSetEnabledAction(true));

        currentDateButton = new JRadioButton("Set current date", false);
        currentDateButton.addActionListener(new DateFieldsSetEnabledAction(false));

        buttonGroup = new ButtonGroup();

        buttonGroup.add(setDateButton);
        buttonGroup.add(currentDateButton);
    }

    private void layoutComponents() {
        setLayout(new GridBagLayout());

        add(setDateButton, new GBC(0,0,3,1).setInsets(5,0,5,5));
        add(currentDateButton, new GBC(3,0,3,1).setInsets(5,0,5,5));

        add(new JLabel("Day"), new GBC(0,1).setInsets(2,3,5,5).setWeight(16,0));
        add(new JLabel("Month"), new GBC(1,1).setInsets(2,3,5,5).setWeight(16,0));
        add(new JLabel("Year"), new GBC(2,1).setInsets(2,3,5,5).setWeight(16,0));
        add(new JLabel("Hours"), new GBC(3,1).setInsets(2,3,5,5).setWeight(16,0));
        add(new JLabel("Minutes"), new GBC(4,1).setInsets(2,3,5,5).setWeight(16,0));
        add(new JLabel("Seconds"), new GBC(5,1).setInsets(2,3,5,5).setWeight(16,0));

        add(dayField, new GBC(0,2).setInsets(0,5,5,5).setWeight(16,0));
        add(monthField, new GBC(1,2).setInsets(0,5,5,5).setWeight(16,0));
        add(yearField, new GBC(2,2).setInsets(0,5,5,5).setWeight(16,0));
        add(hoursField, new GBC(3,2).setInsets(0,5,5,5).setWeight(16,0));
        add(minutesField, new GBC(4,2).setInsets(0,5,5,5).setWeight(16,0));
        add(secondsField, new GBC(5,2).setInsets(0,5,5,5).setWeight(16,0));
    }

    public void setDate(Date date) {
        if (date == null) {
            dayField.setText("");
            monthField.setText("");
            yearField.setText("");
            hoursField.setText("");
            minutesField.setText("");
            secondsField.setText("");
        } else {
            Calendar c = new GregorianCalendar();
            c.setTime(date);
            dayField.setText("" + c.get(Calendar.DAY_OF_MONTH));
            monthField.setText("" + (c.get(Calendar.MONTH) + 1));
            yearField.setText("" + c.get(Calendar.YEAR));
            hoursField.setText("" + c.get(Calendar.HOUR_OF_DAY));
            minutesField.setText("" + c.get(Calendar.MINUTE));
            secondsField.setText("" + c.get(Calendar.SECOND));
        }
    }

    public Date getDate() throws InvalidDateException {
        try {
            if(setDateButton.isSelected()) {
                year = Integer.parseInt(yearField.getText());
                month = Integer.parseInt(monthField.getText());
                day = Integer.parseInt(dayField.getText());
                hours = Integer.parseInt(hoursField.getText());
                minutes = Integer.parseInt(minutesField.getText());
                seconds = Integer.parseInt(secondsField.getText());

                String field = findErrorInDateFields();
                if(field == null) {
                    GregorianCalendar c = new GregorianCalendar(year,month-1,day,hours,minutes,seconds);
                    return c.getTime();
                } else {
                    throw new InvalidDateException("Wrong value in field " + field);
                }
            } else {
                return new Date();
            }
        } catch(NumberFormatException e) {
            throw new InvalidDateException("Cannot read the Date", e);
        }
    }

    private String findErrorInDateFields() throws InvalidDateException {
        if(year < 1) return "Year";
        if(month < 1 || month > 12) return "Month";
        if(day < 1) return "Day";
        if(hours > 23 || hours < 0) return "Hours";
        if(minutes > 59 || minutes < 0) return "Minutes";
        if(seconds > 59 || seconds < 0) return "Seconds";


        boolean isDayCorrect = true;

        if(month == 1) {
            isDayCorrect &= (day <= 31);
        } else if(month == 2) {
            if(year % 4 == 0) {
                isDayCorrect &= (day <= 29);
            } else {
                isDayCorrect &= (day <= 28);
            }
        } else if(month == 3) {
            isDayCorrect &= (day <= 31);
        } else if(month == 4) {
            isDayCorrect &= (day <= 30);
        } else if(month == 5) {
            isDayCorrect &= (day <= 31);
        } else if(month == 6) {
            isDayCorrect &= (day <= 30);
        } else if(month == 7) {
            isDayCorrect &= (day <= 31);
        } else if(month == 8) {
            isDayCorrect &= (day <= 31);
        } else if(month == 9) {
            isDayCorrect &= (day <= 30);
        } else if(month == 10) {
            isDayCorrect &= (day <= 31);
        } else if(month == 11) {
            isDayCorrect &= (day <= 30);
        } else if(month == 12) {
            isDayCorrect &= (day <= 31);
        }

        if(isDayCorrect) {
            return null;
        } else {
            return "Day";
        }
    }


    private class DateFieldsSetEnabledAction implements ActionListener {

        private boolean enabled;

        public DateFieldsSetEnabledAction(boolean enabled) {
            this.enabled = enabled;
        }

        public void actionPerformed(ActionEvent event) {
            dayField.setEnabled(enabled);
            monthField.setEnabled(enabled);
            yearField.setEnabled(enabled);
            hoursField.setEnabled(enabled);
            minutesField.setEnabled(enabled);
            secondsField.setEnabled(enabled);
        }
    }

    public void setDate(int year, int month, int day, int hours,
            int minutes, int seconds) {
        dayField.setText("" + day);
        monthField.setText("" + month);
        yearField.setText("" + year);
        hoursField.setText("" + hours);
        minutesField.setText("" + minutes);
        secondsField.setText("" + seconds);
    }

}
